/*
 * Copyright (C) 2009 Leandro Aparecido <lehphyro@gmail.com>
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *         http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.metalframework.jsf.scope.impl;

import java.util.*;

import org.metalframework.jsf.scope.*;
import org.slf4j.*;


public class FlashScope extends AbstractFacesScope {
	
	private static final String CURRENTLY_IN_USE_ATTRIBUTES = "currentlyInUseAttributes";
	
	private static final Logger logger = LoggerFactory.getLogger(FlashScope.class);

	@Override
	public void set(String name, Object obj) {
		super.set(name, obj);
		addAttributeToCurrentlyInUse(name);
	}
	
	@Override
	public void onEndRequest() {
		Set<String> currentlyInUseAttributes = internalGet(CURRENTLY_IN_USE_ATTRIBUTES);
		Map<String, Object> store = getStore();
		
		if (currentlyInUseAttributes == null) {
			clear();
		} else {
			if (!currentlyInUseAttributes.isEmpty()) {
				logger.debug("Expiring all attributes in the [{}] scope but: {}", getType(), currentlyInUseAttributes);
				
				for (String attributeName : store.keySet()) {
					if (attributeName.startsWith(getPrefix()) &&
						!attributeName.contains(CURRENTLY_IN_USE_ATTRIBUTES) &&
						!currentlyInUseAttributes.contains(getRawName(attributeName))) {
						internalRemove(getRawName(attributeName));
					}
				}
			}
			
			internalRemove(CURRENTLY_IN_USE_ATTRIBUTES);
		}
	}
	
	@Override
	protected FacesScopeType getType() {
		return FacesScopeType.FLASH;
	}

	protected void addAttributeToCurrentlyInUse(String name) {
		// TODO the attributes should be kept independently from other browser pages in the same session
		Set<String> currentlyInUseAttributes = internalGet(CURRENTLY_IN_USE_ATTRIBUTES);
		if (currentlyInUseAttributes == null) {
			currentlyInUseAttributes = new HashSet<String>();
		}
		currentlyInUseAttributes.add(name);
		
		internalSet(CURRENTLY_IN_USE_ATTRIBUTES, currentlyInUseAttributes);
	}
}
